package mya_dc.shared_classes.files_manipulation;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;

/**
 * A wrapper class to allow sending files as objects
 *
 * @author      Adam Levi
 * <br>			MYA
 */
public class FileObject implements Serializable
{
	private static final long serialVersionUID = 1L;
	
	/**
	 * Constructor
	 *
	 * @param file - The file that will be loaded
	 * @param relativePath - The relative path of the file in the project
	 */
	public FileObject(File file, String relativePath) throws IOException
	{
		m_relativePath = relativePath;
		createFileObject(file);
	}
	
	/**
	 * Constructor
	 *
	 * @param file - The file that will be loaded
	 */
	public FileObject(File file) throws IOException
	{
		m_relativePath = "";
		createFileObject(file);	
	}
	
	/**
	 * Writes the object to the path: workingDirectory + m_relativePath + filename
	 *
	 * @param workingDirectory - The directory to save the object at
	 */
	public void writeFile(String workingDirectory) throws IOException
	{
		FileObject.createDirsAccordingToString(workingDirectory, m_relativePath + "\\");
		FileOutputStream outStream = new FileOutputStream(workingDirectory + m_relativePath + "\\" + m_fileMetaData.getName());
		outStream.write(m_fileData);
		outStream.close();
	}
	
	/**
	 * @return The name of the file
	 */
	public String fileName()
	{
		return m_fileMetaData.getName();
	}
	
	/**
	 * @return m_relativePath
	 */
	public String getRelativePath()
	{
		return m_relativePath;
	}
	
	/**
	 * a method to return relative pathname in a given file in a given root
	 * 
	 * @param projectRoot - root
	 * @param filePathName - a path to a file
	 * 
	 * @return The relative pathname in filePathName under projectRoot.
	 */ 
	public static String getRelativePathFromRoot(String projectRoot, String filePathName)
	{
		int index = filePathName.lastIndexOf('\\');
		int len = projectRoot.length();
		if (index <= len)
			return "";
		return filePathName.substring(len,index);
	}
	
	/**
	 * Creates directories in absolutePath according to dirsToCreate.
	 * <br>For instance if absolutePath = "c:\\tmp", and dirsToCreate = "\\dir1\\dir2
	 *		then the function will create the directories c:\\tmp\\dir1\\dir2
	 * 
	 * @param absolutePath - A path in the computer.
	 * @param dirsToCreate - a relative pathname that the function will take the directories from.
	 * 
	 * @return The relative pathname in filePathName under projectRoot.
	 */ 
	public static void createDirsAccordingToString(String absolutePath, String dirsToCreate)
	{
		int endIndex = dirsToCreate.indexOf('\\');
		while(endIndex != -1)
		{
			String dirToCreate = absolutePath + dirsToCreate.substring(0, endIndex);
			File f = new File(dirToCreate);
			f.mkdir();
			endIndex = dirsToCreate.indexOf("\\",endIndex+1);
		}
	}
	
	/**
	 * Deletes a directory and all its sub-directories/files.
	 * 
	 * @param path - A path of a file/directory
	 * 
	 * @return true if and only if the file or directory is successfully deleted; false otherwise
	 */ 
	public static boolean deleteDirectory(File path)
	{
		if (path == null)
			return false;
		if (path.isFile())
		{
			path.delete();
			return true;
		}
	    if( path.exists() ) {
	    	File[] files = path.listFiles();
	    	for(int i=0; i<files.length; i++) {
	    		if(files[i].isDirectory()) {
	    			deleteDirectory(files[i]);
	    		}
	    		else {
	    			files[i].delete();
	    		}
	    	}
	    }
	    return( path.delete() );
  	}
	
	/**
	 * Load the specified file into 'this'.
	 * 
	 * @param file - a file.
	 * 
	 */ 
	private void createFileObject(File file) throws IOException
	{
		byte[] tmpArr = new byte[(int)file.length()];
		FileInputStream inStream = new FileInputStream(file);
		inStream.read(tmpArr);
		m_fileData = tmpArr;
		m_fileMetaData = file;
		inStream.close();	
	}
	private byte[] m_fileData;
	private String m_relativePath;
	private File m_fileMetaData;
}